package org.bugjail.dataaccess.jdbc.objects;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedList;
import java.util.List;

import org.bugjail.data.Suite;
import org.bugjail.data.TestDesign;
import org.bugjail.data.TestRound;
import org.bugjail.dataaccess.DAOFactory;
import org.bugjail.dataaccess.jdbc.connection.QueryException;
import org.bugjail.dataaccess.jdbc.connection.QueryManager;
import org.bugjail.dataaccess.objects.SuiteDAO;
import org.bugjail.dataaccess.objects.TestDesignDAO;

public class JDBCSuiteDAO implements SuiteDAO {
	
	private final String PROPERTIES_FILE = "/org/bugjail/dataaccess/jdbc/properties/suitedao.properties";

	private final String PROPERTY_RETRIEVE_BY_TESTDESIGN = "retrieve.bytestdesign";
	private final String PROPERTY_RETRIEVE_BY_TESTDESIGN_NOT_ON_ROUND = "retrieve.bytestdesign.notonround";
	private final String PROPERTY_RETRIEVE_BY_ID = "retrieve.byid";
	private final String PROPERTY_INSERT = "insert";
	private final String PROPERTY_UPDATE = "update";
	
	private Suite extractSuiteFromResultSet(ResultSet rs, QueryManager queryManager, TestDesign testDesign) throws SQLException {
		Suite suite = new Suite();
		int id = rs.getInt("id");
		suite.setId(id);

		if (testDesign == null) {
			TestDesignDAO testDesignDao = DAOFactory.getDAOFactory().getTestDesignDAO();
			suite.setTestDesign(testDesignDao
					.retrieveById(rs.getInt("testdesign_id")));
		} else {
			suite.setTestDesign(testDesign);
		}
		suite.setName(rs.getString("name"));
		suite.setDescription(rs.getString("description"));

		return suite;
	}
	
	@Override
	public List<Suite> retrieveSuitesOfTestDesign(TestDesign testDesign) {
		List<Suite> suites = new LinkedList<Suite>();
		QueryManager queryManager = null;
		try {
			try {
				queryManager = new QueryManager(PROPERTIES_FILE);
				PreparedStatement statement = queryManager
						.getPreparedStatement(PROPERTY_RETRIEVE_BY_TESTDESIGN);
				statement.setInt(1, testDesign.getId());
				ResultSet rs = statement.executeQuery();
				while (rs.next()) {
					suites.add(extractSuiteFromResultSet(rs,
							queryManager, testDesign));
				}
			} finally {
				QueryManager.close(queryManager);
			}
		} catch (Exception e) {
			throw new QueryException(e.getMessage());
		}
		return suites;
	}

	@Override
	public void create(Suite element) {
		QueryManager queryManager = null;
		//List<Integer> termGenKeys = new LinkedList<Integer>();
		try {
			try {
				queryManager = new QueryManager(PROPERTIES_FILE);
				PreparedStatement statement = queryManager
						.getPreparedStatement(PROPERTY_INSERT);
				statement.setString(1, element.getName());
				statement.setString(2, element.getDescription());
				statement.setInt(3, element.getTestDesign().getId());
				statement.executeUpdate();
				//ResultSet rs = statement.getGeneratedKeys();
				//int testDesignKey = 0;
				//if (rs.next()) {
				//	testDesignKey = rs.getInt(1);
				//}

				//TermDAO termDao = JDBCDAOFactory.getDAOFactory().getTermDAO();
				//for (Term term : element.getTerms()) {
				//	termGenKeys.add(termDao.createAndReturnGeneratedKeys(term));
				//}

				//for (int i = 0; i < termGenKeys.size(); i++) {
				//	this.createTestDesignTermAssociation(testDesignKey,
				//			termGenKeys.get(i), queryManager);
				//}

				QueryManager.commit(queryManager);

			} finally {
				QueryManager.close(queryManager);
			}
		} catch (Exception e) {
			QueryManager.rollback(queryManager);
			throw new QueryException(e.getMessage());
		}
	}

	@Override
	public void delete(Suite element) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public List<Suite> retrieveAll() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Suite retrieveById(int id) {
		Suite suite = null;
		QueryManager queryManager = null;
		try {
			try {
				queryManager = new QueryManager(PROPERTIES_FILE);
				PreparedStatement statement = queryManager
						.getPreparedStatement(PROPERTY_RETRIEVE_BY_ID);
				statement.setInt(1, id);
				ResultSet rs = statement.executeQuery();
				if (rs.next()) {
					suite = extractSuiteFromResultSet(rs, queryManager, null);
				}
			} finally {
				QueryManager.close(queryManager);
			}
		} catch (Exception e) {
			throw new QueryException(e.getMessage());
		}
		return suite;
	}

	@Override
	public List<Suite> retrieveByName(String name) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void update(Suite element) {
		QueryManager queryManager = null;
		//List<Integer> termGenKeys = new LinkedList<Integer>();
		try {
			try {
				queryManager = new QueryManager(PROPERTIES_FILE);
				PreparedStatement statement = queryManager
						.getPreparedStatement(PROPERTY_UPDATE);
				statement.setString(1, element.getName());
				statement.setString(2, element.getDescription());
				statement.setInt(3, element.getTestDesign().getId());
				statement.setInt(4, element.getId());
				statement.executeUpdate();

				QueryManager.commit(queryManager);

			} finally {
				QueryManager.close(queryManager);
			}
		} catch (Exception e) {
			QueryManager.rollback(queryManager);
			throw new QueryException(e.getMessage());
		}
	}

	@Override
	public List<Suite> retrieveSuitesOfTestDesignNotOnRound(
			TestDesign testDesign, TestRound testRound) {
		List<Suite> suites = new LinkedList<Suite>();
		QueryManager queryManager = null;
		try {
			try {
				queryManager = new QueryManager(PROPERTIES_FILE);
				PreparedStatement statement = queryManager
						.getPreparedStatement(PROPERTY_RETRIEVE_BY_TESTDESIGN_NOT_ON_ROUND);
				statement.setInt(1, testDesign.getId());
				statement.setInt(2, testRound.getId());
				ResultSet rs = statement.executeQuery();
				while (rs.next()) {
					suites.add(extractSuiteFromResultSet(rs,
							queryManager, testDesign));
				}
			} finally {
				QueryManager.close(queryManager);
			}
		} catch (Exception e) {
			throw new QueryException(e.getMessage());
		}
		return suites;
	}

}
